package us.gaaoc.framework.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.Hibernate;

import us.gaaoc.cms.sustain.vo.Address;
import us.gaaoc.cms.sustain.vo.CaseEvent;
import us.gaaoc.cms.sustain.vo.CaseFiling;
import us.gaaoc.cms.sustain.vo.CaseOfficial;
import us.gaaoc.cms.sustain.vo.CaseParty;
import us.gaaoc.cms.sustain.vo.Organization;
import us.gaaoc.framework.dao.ModelFacade;
import us.gaaoc.framework.model.CaseRecord;
import us.gaaoc.framework.model.Court;
import us.gaaoc.framework.model.CourtEventType;
import us.gaaoc.framework.model.CourtEvents;
import us.gaaoc.framework.model.LocalCourtEventType;
import us.gaaoc.framework.model.LocalParticipantRelationship;
import us.gaaoc.framework.model.OrgParticipants;
import us.gaaoc.framework.model.OrganizationAddress;
import us.gaaoc.framework.model.PersonAddress;
import us.gaaoc.framework.model.PersonParticipants;

public class DomToSustainConverter {
	
	public static CaseFiling createCaseFiling(ModelFacade mf,CaseRecord cr, Court court) {

		// 1. load data
		// 		b7006e6c-695c-11dd-945f-00301b45ff56	 
		Hibernate.initialize(cr.getPersonParticipants());
		Hibernate.initialize(cr.getOrgParticipants());
		Hibernate.initialize(cr.getCourtEvents());
		
		List<PersonParticipants> pParticipantsList = cr.getPersonParticipants();
		List<OrgParticipants> oParticipantsList = cr.getOrgParticipants();
		List<CourtEvents> courtEventList = cr.getCourtEvents();

		List<OrgParticipants> initiatingPartyOrganizationList = new ArrayList<OrgParticipants>();
		List<PersonParticipants> initiatingPartyPersonList = new ArrayList<PersonParticipants>();
		List<PersonParticipants> defendentPartyPersonList = new ArrayList<PersonParticipants>();
		List<PersonParticipants> witnessPersonList = new ArrayList<PersonParticipants>();
		List<PersonParticipants> plantiffsAttorneyList = new ArrayList<PersonParticipants>();
		List<PersonParticipants> defendentsAttorneyList = new ArrayList<PersonParticipants>();

		for (OrgParticipants o : oParticipantsList) {
			if (o.getRelationship().getCode() == 1) // for initiating party
				// organization list
				initiatingPartyOrganizationList.add(o);
		}
		for (PersonParticipants o : pParticipantsList) {
			if (o.getRelationship().getCode() == 1) // for initiating party
				// person list
				initiatingPartyPersonList.add(o);
			else if (o.getRelationship().getCode() == 2) // for defendent
				// party person list
				defendentPartyPersonList.add(o);
			else if (o.getRelationship().getCode() == 3) // for witness
				// person list
				witnessPersonList.add(o);
			else if (o.getRelationship().getCode() == 4) // for plantiff's
				// Attorneys
				plantiffsAttorneyList.add(o);
			else if (o.getRelationship().getCode() == 5) // for defendent's
				// Attorneys
				defendentsAttorneyList.add(o);
		}

		// 2. transfer data into CMS objects

		CaseFiling caseFiling = new CaseFiling();
		caseFiling.setCategory(cr.getLocalCaseCategory().getCmsCode());
		caseFiling.setDivID(cr.getLocalCaseDivision().getCmsCode());
		caseFiling.setType(cr.getLocalCaseType().getCmsCode());
		caseFiling.setFilingType(cr.getLocalCaseFilingType().getCmsCode());
		// caseFiling.setDate(new Date());
		caseFiling.setDate(getAttorneySubmissionDate(cr.getUuid(),mf));

		// a. for initiating party organization list
		List<CaseParty> ipoList = new ArrayList<CaseParty>();
		LocalParticipantRelationship localParticipantRelationship = mf
			.findLocalParticipantRelationship(court, 1);
		for (OrgParticipants o : initiatingPartyOrganizationList) {

			String orgName = o.getOrganizations().getName().replaceAll("[^a-zA-Z0-9 ]","");

			List<Address> addList = new ArrayList<Address>();
			List<OrganizationAddress> orgAddList = o.getOrganizations()
			.getAddresses();
			for (OrganizationAddress orgAdd : orgAddList) {
				Address add = new Address();
				add.setStreet1(orgAdd.getAddress().getStreetFullText());
				add.setStreet2(orgAdd.getAddress().getStreetExtensionText());
				add.setCity(orgAdd.getAddress().getCityName());
				add.setState(orgAdd.getAddress().getState());
				add.setZip(orgAdd.getAddress().getZipCode());
				addList.add(add);
			}
			// Organization org = new Organization();
			Organization org = new Organization(orgName, addList);
			CaseParty cp = new CaseParty();
			cp.setOrg(org);
			cp.setCmsTypeCode(localParticipantRelationship.getCmsCode()); // @todo
			ipoList.add(cp);
		}
		caseFiling.setCaseInitiatingPartyOrgList(ipoList);

		// b. for initiating party person list
		List<CaseParty> ippList = getCMSParties(mf,initiatingPartyPersonList,
				court, 1);
		caseFiling.setInitatingPartyPersonList(ippList);

		// c. for defendent party person list
		List<CaseParty> dppList = getCMSParties(mf,defendentPartyPersonList,
				court, 2);
		caseFiling.setCaseDefendantParty(dppList);

		// d. for witness list
		List<CaseParty> witList = getCMSParties(mf,witnessPersonList, court,
				3);
		caseFiling.setWitnessList(witList);

		// e. for plantiff attorney
		List<CaseOfficial> paList = getCMSOfficial(mf,plantiffsAttorneyList,
				court, 4);
		caseFiling.setProsecutionAttorneyList(paList);

		// f. for defendent attorney List
		List<CaseOfficial> daList = getCMSOfficial(mf,defendentsAttorneyList,
				court, 5);
		caseFiling.setDefenseAttorneyList(daList);

		// g. for scheduled court date
		List<CaseEvent> eventList = new ArrayList<CaseEvent>();
		for (CourtEvents ce : courtEventList) {
			CourtEventType cet = ce.getEventType();
			if (cet.getCode() == 1) { // is a court date event
				LocalCourtEventType lcet = mf
				.findLocalCourtEventType(court, 1);
				CaseEvent caseEvent = new CaseEvent();
				caseEvent.setDate(ce.getEventTime());
				caseEvent.setType(lcet.getCmsCode()); // @TODO
				eventList.add(caseEvent);
			}
		}
		caseFiling.setEventList(eventList);

		return caseFiling;
	}

	/**
	 * This method transforms a PersonParticipants list into a CaseOfficial list
	 * for import to sustain.
	 * 
	 * @param participantList
	 * @return
	 */
	private static List<CaseOfficial> getCMSOfficial(
			ModelFacade mf,
			List<PersonParticipants> participantList, Court court,
			int participantRelationshipCode) {

		LocalParticipantRelationship localParticipantRelationship = mf.findLocalParticipantRelationship(court,
				participantRelationshipCode);

		List<CaseOfficial> caseOfficialList = new ArrayList<CaseOfficial>();
		for (PersonParticipants off : participantList) {
			String firstName = off.getPerson().getFirstName().replaceAll("[^a-zA-Z0-9 ]","");								
			String middleName = "";
			if(	off.getPerson().getMiddleName() != null)
			{
				middleName = off.getPerson().getMiddleName().replaceAll("[^a-zA-Z0-9 ]","");
			}
			String lastName = off.getPerson().getLastName().replaceAll("[^a-zA-Z0-9 ]","");
			String suffix = "";
			if(	off.getPerson().getMiddleName() != null)
			{
				suffix = off.getPerson().getSuffixName().replaceAll("[^a-zA-Z0-9 ]","");
			}
			//String barId = off.getPerson().getAttorney().getBarID();
			String barId = mf.getBarID(off.getPerson(),court);
			us.gaaoc.cms.sustain.vo.Person p = new us.gaaoc.cms.sustain.vo.Person(
					firstName, middleName, lastName, suffix);
			CaseOfficial co = new CaseOfficial();
			co.setBarID(barId);
			co.setCmsTypeCode(localParticipantRelationship.getCmsCode());
			co.setPerson(p);
			caseOfficialList.add(co);
		}
		return caseOfficialList;
	}

	/**
	 * This method transforms a Person participant list into a case party list
	 * for import to sustain.
	 * 
	 * @param participantList
	 * @return
	 */
	private static List<CaseParty> getCMSParties(
			ModelFacade mf,
			List<PersonParticipants> participantList, Court court,
			int participantRelationshipCode) {

		LocalParticipantRelationship localParticipantRelationship = mf.findLocalParticipantRelationship(court,
				participantRelationshipCode);

		List<CaseParty> casePartyList = new ArrayList<CaseParty>();
		for (PersonParticipants pp : participantList) {
			String firstName = pp.getPerson().getFirstName().replaceAll("[^a-zA-Z]","");
			String middleName;
			if(pp.getPerson().getMiddleName() == null)
			{
				middleName = "";
			}else{
				middleName = pp.getPerson().getMiddleName().replaceAll("[^a-zA-Z]","");
			}
			
			
			
			
			
			
			String lastName = pp.getPerson().getLastName().replaceAll("[^a-zA-Z]","");
			String suffix;
			if(pp.getPerson().getSuffixName() == null)
				{
				suffix = "";
				
				}else{
					suffix = pp.getPerson().getSuffixName().replaceAll("[^a-zA-Z]","");	
				}
			
			
			

			List<Address> addList = new ArrayList<Address>();
			pp.getPerson().getAddresses();
			List<PersonAddress> pAddList = pp.getPerson().getAddresses();
			for (PersonAddress pa : pAddList) {
				Address add = new Address();
				
				 add.setStreet1(pa.getAddress().getStreetFullText());
				 add.setStreet2(pa.getAddress().getStreetExtensionText());
				 add.setCity(pa.getAddress().getCityName()); 
				 add.setState(pa.getAddress().getState());
				 add.setZip(pa.getAddress().getZipCode());
				 
				addList.add(add);
			}
			us.gaaoc.cms.sustain.vo.Person p = new us.gaaoc.cms.sustain.vo.Person(
					firstName, middleName, lastName, suffix, addList);
			CaseParty cp = new CaseParty();
			cp.setCmsTypeCode(localParticipantRelationship.getCmsCode()); // @todo
			cp.setPerson(p);
			casePartyList.add(cp);
		}
		return casePartyList;
	}
	

	private static Date getAttorneySubmissionDate(String caseUuid,ModelFacade mf) {
		Date attorneySubmissionDate = null;
		attorneySubmissionDate = mf.findAttorneySubmissionDate(caseUuid);
		return attorneySubmissionDate;
	}
	
}
